home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
45975
/
45975.xpi
/
content
/
remindwords.js
< prev
next >
Wrap
Text File
|
2009-11-23
|
9KB
|
230 lines
/*
* Copyright (c) 2009 Bui Viet Thanh (thanhbv@gmail.com).
*
* This file is part of clicknlearn.
*
* clicknlearn is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* clicknlearn is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with clicknlearn. If not, see <http://www.gnu.org/licenses/>.
*/
Components.utils.import("resource://clicknlearn/cnldao.js");
Components.utils.import("resource://clicknlearn/ext/Observers.js");
//////////////////////////
function Remind() {
}
Remind.prototype.remindCurrentWord = function(){
var word = CNL.DICLOOKUP.currentWord.replace("'", "''");
var remind = CNL.currentDoc.getElementById('remindbox').value.replace("'", "''");
CNL.DICLOOKUP.currentWord.replace("'", "''");
var r = {"id": word, "remind": remind, "originalUrl": content.location.href, "read": 0};
CNL_DAO.create(r);
Observers.notify("cnl_wordAddOrModify", word);
this.highlightWord(CNL.DICLOOKUP.currentWord);
CNL.DICLOOKUP.clearAll();
}
Remind.prototype.removeCurrentWord = function(){
CNL_DAO.setWordRead(CNL.DICLOOKUP.currentWord);
Observers.notify("cnl_wordAddOrModify", CNL.DICLOOKUP.currentWord);
// this.unHighlightWord(CNL.DICLOOKUP.currentWord);
CNL.DICLOOKUP.clearAll();
}
Remind.prototype.nodeDepth = function(node){
var depth = 0;
var body = window.content.document.body;
while(node != body){
depth++;
node = node.parentNode;
}
return depth;
}
Remind.prototype.surround = function(range){
//range.startContainer is always TextNode?
var doc = window.content.document;
var surroundNode = doc.createElement("span");
surroundNode.setAttribute("class", "clicknlearnRemind");
if(range.startContainer.parentNode == range.endContainer.parentNode){
range.surroundContents(surroundNode);
return;
}
//find commond parent node of the start point & end point
var s = range.startContainer.parentNode;
var sdepth = this.nodeDepth(s);
var e = range.endContainer.parentNode;
var edepth = this.nodeDepth(e);
for(;sdepth > edepth; sdepth--)
s = s.parentNode;
for(;edepth > sdepth; edepth--)
e = e.parentNode;
while(s != e){
s = s.parentNode;
e = e.parentNode;
}
var p = s;//common parent
//do surround
s = range.startContainer;
e = range.endContainer;
var eOffset = range.endOffset;
while(s.parentNode != p){
range.setEnd(s.parentNode, s.parentNode.childNodes.length);
range.surroundContents(surroundNode.cloneNode(true));
range.setStartAfter(s.parentNode);
s = s.parentNode;
}
s = range.startContainer;
var sOffset = range.startOffset;
range.setEnd(e, eOffset);
while(e.parentNode != p){
range.setStart(e.parentNode, 0);
range.surroundContents(surroundNode.cloneNode(true));
range.setEndBefore(e.parentNode);
e = e.parentNode;
}
range.setStart(s, sOffset);
range.surroundContents(surroundNode);
}
/**
* See: nsIFind - http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/interfaces/nsIFind
* Range - http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
*/
Remind.prototype.highlightWords = function(){
var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance()
.QueryInterface(Components.interfaces.nsIFind);
var doc = window.content.document;
var body = doc.body;
var count = body.childNodes.length;
var mSearchRange = doc.createRange();
var mStartPt = doc.createRange();
var mEndPt = doc.createRange();
mSearchRange.setStart(body, 0);
mSearchRange.setEnd(body, count);
mEndPt.setStart(body, count);
mEndPt.setEnd(body, count);
var statement = CNL_DAO.selectUnreadWordsStm();
//if range represent 'in' in a word 'inova' then we should not highlight it
var isRangeAWord, i;
statement.executeAsync({
handleResult: function(aResultSet) {
for (var row = aResultSet.getNextRow(); row; row = aResultSet.getNextRow()) {
var word = row.getResultByName("word");
var rs = new Array();
mStartPt.setStart(body, 0);
mStartPt.setEnd(body, 0);
var foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
while(foundRange != null){
//TODO haven't tested
//check start of a word:
// alert(word + ": start: " + foundRange.startContainer.nodeType + ", " + foundRange.startOffset +
// ", end: " + foundRange.endContainer.nodeType + ", " + foundRange.endOffset);
//TODO foundRange.startContainer & endContainer is always TEXT_NODE???
if(foundRange.startContainer.nodeType != Node.TEXT_NODE)
isRangeAWord = true;
else{
i = foundRange.startOffset;
isRangeAWord = i == 0
|| ! CNLUtils.VALID_CHARS.test(foundRange.startContainer.textContent[i - 1]);
}
//check end of a word:
//Only check if check start successfully
if(isRangeAWord)
if(foundRange.endContainer.nodeType == Node.TEXT_NODE){
i = foundRange.endOffset;
isRangeAWord = i == foundRange.endContainer.textContent.length
|| ! CNLUtils.VALID_CHARS.test(foundRange.endContainer.textContent[i]);
}
if(isRangeAWord)
rs[rs.length] = foundRange;
mStartPt.setStart(foundRange.endContainer, foundRange.endOffset);
mStartPt.setEnd(foundRange.endContainer, foundRange.endOffset);
foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
}
for(i=0; i<rs.length; i++)
CNL.REMIND.surround(rs[i]);
}
},
handleError: function(aError) {
// print("Error: " + aError.message);
},
handleCompletion: function(aReason) {
// if (aReason != Components.interfaces.mozIStorageStatementCallback.REASON_FINISHED)
// print("Query canceled or aborted!");
}
});
}
Remind.prototype.highlightWord = function(word){
var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance()
.QueryInterface(Components.interfaces.nsIFind);
var doc = window.content.document;
var body = doc.body;
var count = body.childNodes.length;
var mSearchRange = doc.createRange();
var mStartPt = doc.createRange();
var mEndPt = doc.createRange();
mSearchRange.setStart(body, 0);
mSearchRange.setEnd(body, count);
mEndPt.setStart(body, count);
mEndPt.setEnd(body, count);
//if range represent 'in' in a word 'inova' then we should not highlight it
var isRangeAWord, i;
var rs = new Array();
mStartPt.setStart(body, 0);
mStartPt.setEnd(body, 0);
var foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
while(foundRange != null){
//TODO haven't tested
//check start of a word:
//TODO foundRange.startContainer & endContainer is always TEXT_NODE???
if(foundRange.startContainer.nodeType != Node.TEXT_NODE)
isRangeAWord = true;
else{
i = foundRange.startOffset;
isRangeAWord = i == 0
|| ! CNLUtils.VALID_CHARS.test(foundRange.startContainer.textContent[i - 1]);
}
//check end of a word:
//Only check if check start successfully
if(isRangeAWord)
if(foundRange.endContainer.nodeType == Node.TEXT_NODE){
i = foundRange.endOffset;
isRangeAWord = i == foundRange.endContainer.textContent.length
|| ! CNLUtils.VALID_CHARS.test(foundRange.endContainer.textContent[i]);
}
if(isRangeAWord)
rs[rs.length] = foundRange;
mStartPt.setStart(foundRange.endContainer, foundRange.endOffset);
mStartPt.setEnd(foundRange.endContainer, foundRange.endOffset);
foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
}
for(i=0; i<rs.length; i++)
CNL.REMIND.surround(rs[i]);
}